package com.hhs.storage.config.jwt;

/**
 * @Auther: shadow
 * @Date: 2018/10/31 17:02
 * @Description:
 *
 * 参考  https://blog.csdn.net/u010004082/article/details/79351216
 */
import java.security.Key;
import java.util.Calendar;
import java.util.Date;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/*
 * 构造及解析jwt的工具类
 * 将用户信息加密到token里，服务器不保存任何用户信息。
 * 服务器通过使用保存的密钥验证token的正确性，只要正确即通过验证。
 * jwt优点是在分布式系统中，很好地解决了单点登录问题，很容易解决了session共享的问题。
 *    缺点是无法作废已颁布的令牌/不易应对数据过期。
 *
 *     ajax调用时，加入下面
 *     headers: {
                    Authorization: "" + token,
                },
 */
public class JwtHelper {
    public static Claims parseJWT(String jsonWebToken, String base64Security){
        try
        {
            Claims claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(base64Security))
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims;
        }
        catch(Exception ex)
        {
            return null;
        }
    }

    /**
     * 生成token
     * @param userId
     * @param role
     * @param base64Security
     * @return
     */
    public static String createJWT(String name, String userId, String role,  String base64Security)
    {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;


        //生成签名密钥
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //添加构成JWT的参数
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
                .claim("role", role)
                .claim("userName", name)
                .claim("userId", userId)
                .signWith(signatureAlgorithm, signingKey)
                ;
        //有效期一天
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.DATE, 1);
        Date expiresDate = nowTime.getTime();
        builder.setExpiration(expiresDate).setNotBefore(new Date());
        //生成JWT
        return builder.compact();
    }
}
